<?php
declare(strict_types=1);

namespace Service\SearchService;

use Service\BaseService;
use Service\Code\Normal;
use Service\SearchService\Index\StoreCommodityIndex;
use Service\SearchService\Index\ChannelCommodityIndex;

/**
 * TO C/B SBBC搜索服务中心
 */
class SearchService extends BaseService 
{
    const T_C = 'qd';
    const T_B = 'qqc';

    const COMMODITY_CHANGE     = 'CommodityChange';
    const COMMODITY_DEL        = 'CommodityBatchDel';
    const COMMODITY_ALL_DEL    = 'CommodityAllDel';
    const COMMODITY_DEL_BY_STOREID  = 'CommodityDelByStoreId';
     //消息变化类型
     protected $action = [
        self::COMMODITY_CHANGE     => 'addMultiDoc',
        self::COMMODITY_DEL        => 'deleteMultiDoc',
        self::COMMODITY_ALL_DEL    => 'deleteAllMultiDoc',
        self::COMMODITY_DEL_BY_STOREID  => 'deleteMultiDocByStoreID'
    ]; 

    /**
     * 搜索建议功能
     * @param array $param
     */
    public function searchSuggest( array $param)
    {
        if( empty($param['type']) ) {
            return Normal::returnCode(Normal::FAIL,"搜索类型type不能为空");
        }
        
        $type = $param['type'];
        if( !in_array($type, [self::T_C,self::T_B]) ) {
            return Normal::returnCode(Normal::FAIL,"搜索类型type不正确");
        }
        
        if( $type == self::T_C && empty($param['mn_sid']) ) {
            return Normal::returnCode(Normal::FAIL,"mn_sid不能为空");
        }
        
        if( $type == self::T_B && empty($param['cid']) ) {
            return Normal::returnCode(Normal::FAIL,"cid不能为空");
        }
        
        if( empty($param['keyword']) ) {
            return Normal::returnCode(Normal::FAIL,"keyword不能为空");
        }
        
        if( empty($param['limit']) ) {
            return Normal::returnCode(Normal::FAIL,"limit不能为空");
        }
        
        if( $type == self::T_C ) {//C端
            return StoreCommodityIndex::instance()->searchSuggest($param);
        } else {//B端
            return ChannelCommodityIndex::instance()->searchSuggest($param);
        }
    }
    
    /**
     * 搜索功能
     * @param array $param
     */
    public function searchCommodityList( array $param)
    {
        if( empty($param['type']) ) {
            return Normal::returnCode(Normal::FAIL,"搜索类型type不能为空");
        }
        
        $type = $param['type'];
        if( !in_array($type, [self::T_C,self::T_B]) ) {
            return Normal::returnCode(Normal::FAIL,"搜索类型type不正确");
        }
        
        if( $type == self::T_C && empty($param['mn_sid']) ) {
            return Normal::returnCode(Normal::FAIL,"mn_sid不能为空");
        }
        
        if( $type == self::T_B && empty($param['cid']) ) {
            return Normal::returnCode(Normal::FAIL,"cid不能为空");
        }
        
        if( empty($param['keyword']) && empty($param['class_id']) )
        {
            return Normal::returnCode(Normal::FAIL,"keyword和class_id不能同时为空");
        }
        
        if( $type == self::T_C ) {//C端
            return StoreCommodityIndex::instance()->search($param);
        } else {//B端
            return ChannelCommodityIndex::instance()->search($param);
        }
    }

    /**
     * 搜索功能
     * @param array $param
     */
    public function searchBrandList( array $param)
    {
        if( empty($param['type']) ) {
            return Normal::returnCode(Normal::FAIL,"搜索类型type不能为空");
        }

        $type = $param['type'];
        if( !in_array($type, [self::T_C,self::T_B]) ) {
            return Normal::returnCode(Normal::FAIL,"搜索类型type不正确");
        }

        if( $type == self::T_C && empty($param['mn_sid']) ) {
            return Normal::returnCode(Normal::FAIL,"mn_sid不能为空");
        }

        if( $type == self::T_B && empty($param['cid']) ) {
            return Normal::returnCode(Normal::FAIL,"cid不能为空");
        }

        if( empty($param['keyword']) && empty($param['class_id']) )
        {
            return Normal::returnCode(Normal::FAIL,"keyword和class_id不能同时为空");
        }

        if( $type == self::T_C ) {//C端
            return StoreCommodityIndex::instance()->searchBrand($param);
        } else {//B端
            return ChannelCommodityIndex::instance()->searchBrand($param);
        }
    }

    /**
     * 同步文档
     * @param array $param
     */
    public function SyncMultiDoc(array $param,string $type)
    {

        if( empty($param['actionType']) ) {
            return Normal::returnCode(Normal::FAIL,"actionType不能为空");
        }
        
        if ( !isset($this->action[$param['actionType']]) ) {
            $str = \implode("，", array_keys($this->action));
            return Normal::returnCode(Normal::FAIL,"actionType不能为空，或必须在[{$str}]之间");
        }

        if( empty($type) || !in_array($type,[self::T_C,self::T_B]) ) {
            $str = self::T_C.'、'.self::T_B;
            return Normal::returnCode(Normal::FAIL,"type不能为空，或必须在[{$str}]之间");
        }
        
        if( empty($param['datas']) ) {
            return Normal::returnCode(Normal::SUC,"datas数据为空，无须处理");
        }

        if( $type == self::T_C ) {
            $index = StoreCommodityIndex::instance();
        }else{
            $index = ChannelCommodityIndex::instance();
        }

        $actionMethod = $this->action[$param['actionType']];
        return $index->{$actionMethod}($param);
    }

    
    public function getKeyword($originalKeyword) {
        
        if (empty($originalKeyword)) {
            return [];
        }
        
        $searchKey = strtolower($originalKeyword);
        $result = [];
        
        $regex = "/(?<!\S)(?:[1-9]|10)\b(?!\S)/u";
        // $regex = "/(?<!\d)(?<!\S)(?:[1-9]|10)\b(?![A-Za-z\d])/";
        // $regex = "/\b\d{1,1}\b/";
        // $regex = "/\b\d+\b(?!.\d)/";
        // $regex = "/0|[1-9][0-9]*|-[1-9][0-9]*/i";
        preg_match_all($regex, $searchKey, $matches);
        $useMatches = array_filter($matches[0], function($x) {
            return strlen($x) == 1;
        });
    
        $regex = "/(?:^|[^\p{Han}])([零一二三四五六七八九壹贰叁肆伍陆柒捌玖]+)(?=$|[^\p{Han}])/u";
        preg_match_all($regex, $searchKey, $matches);
        $useMatches = array_merge($useMatches, $matches[0]);

        $result[] = $searchKey;

        if (!empty($useMatches)) {
            foreach ($useMatches as $useMatch) {
                $tempResult = [];
                foreach ($result as $r) {
                    $temp = str_replace($useMatch, $this->getNewValue($useMatch), $r);
                    $tempResult[] = $temp;
                }
                $result = array_merge($result, $tempResult);
            }
        }
    

        $result[] = strtolower($originalKeyword);

        // $this->stringListAddRange($result, "'", "’");
        // $this->stringListAddRange($result, "’", "'");
        // $this->stringListAddRange($result, "'", "‘");
        // $this->stringListAddRange($result, "‘", "'");
        // $this->stringListAddRange($result, "(", "（");
        // $this->stringListAddRange($result, "（", "(");
        // $this->stringListAddRange($result, ")", "）");
        // $this->stringListAddRange($result, "）", ")");
        // $this->stringListAddRange($result, "{", "｛");
        // $this->stringListAddRange($result, "｛", "{");
        // $this->stringListAddRange($result, "}", "｝");
        // $this->stringListAddRange($result, "｝", "}");
        // $this->stringListAddRange($result, ";", "；");
        // $this->stringListAddRange($result, "；", ";");
        // $this->stringListAddRange($result, ":", "：");
        // $this->stringListAddRange($result, "：", ":");
        // $this->stringListAddRange($result, ",", "，");
        // $this->stringListAddRange($result, "，", ",");

        return  implode(" ", array_values(array_unique($result)));
    }
    
    public function getNewValue($value) {
        $cc = explode(" ",$value);
        $result = "";
        foreach ($cc as $c) {
            $result .= $this->getSingleNumber($c);
        }
        return $result;
    }

    public function getSingleNumber($value) {
        if (is_numeric($value)) {
            $num = intval($value);
            switch ($num) {
                case 0:
                    return "零";
                case 1:
                    return "一";
                case 2:
                    return "二";
                case 3:
                    return "三";
                case 4:
                    return "四";
                case 5:
                    return "五";
                case 6:
                    return "六";
                case 7:
                    return "七";
                case 8:
                    return "八";
                case 9:
                    return "九";
                default:
                    return "";
            }
        } else {
            switch ($value) {
                case "零":
                    return "0";
                case "一":
                case "壹":
                    return "1";
                case "二":
                case "贰":
                    return "2";
                case "三":
                case "叁":
                    return "3";
                case "四":
                case "肆":
                    return "4";
                case "五":
                case "伍":
                    return "5";
                case "六":
                case "陆":
                    return "6";
                case "七":
                case "柒":
                    return "7";
                case "八":
                case "捌":
                    return "8";
                case "九":
                case "玖":
                    return "9";
                default:
                    return "";
            }
        }
    }
    
    
    public function stringListAddRange(&$result, $search, $replace) {
        $tempResult = [];
        foreach ($result as $r) {
            $temp = str_replace($search, $replace, $r);
            $tempResult[] = $temp;
        }
        $result = array_merge($result, $tempResult);
    }
    
}